/**
 * 1.指数运算符
 */
const a = 2 ** 3        // 8

// 右结合，而不是常见的左结合
const a1 = 2 ** 2 ** 3 // 256   2 ** (2 ** 3)

// 指数运算符可以与等号结合，形成一个新的赋值运算符（**=）
let a3 = 2
a3 **= 3       // 8   a3 = a3 * a3 * a3



/**
 * 2.可选链 ?.
 * 判断左侧的对象是否为null或undefined。是，返回undefined
 */

// 判断方法是否存在
const a4 = {}
a4.fn?.()  // undefined  判断a4.fn是否为null或undefined 为undefined 返回undefined

// 判断对象是否存在
a4?.prop // undefined
a4?.[prop] // undefined

// 短路机制
a5?.[++a6] // 链判断运算符一旦为真，右侧的表达式就不再求值 a5是undefined或null，那么a6不会进行递增运算

// 括号的影响 一般来说，使用?.运算符的场合，不应该使用圆括号
(a7?.a8).a9 // (a7 == null ? undefined : a7.a8).a9

/**
 * 空值运算符 ??
 * 只有运算符左侧的值为null或undefined时，才会返回右侧的值
 */
const a10 = {}
a10.a11 ?? 100 // 100

/**
 * 逻辑赋值运算符
 * ||= (或赋值运算符)  &&=(与赋值运算符)  ??=(赋值运算符)
 */ 
a12 ||= a13 // a12 || (a12 = a13)
a12 &&= a13 // a12 && (a12 = a13)
a12 ??= a13 // a12 || (a12 = a13)